---
title: Modules and Automatic Discovery
description: Learn how to use Terraform modules effectively with Terrateam and simplify your workflow with automatic module discovery
---

import { Steps } from '@astrojs/starlight/components';

Terraform modules are a powerful way to encapsulate and reuse common infrastructure components across your Terraform projects. Terrateam supports working with Terraform modules seamlessly, allowing you to trigger plans and applies when changes are made to your modules or the directories that depend on them. Additionally, Terrateam's automatic module discovery feature simplifies your workflow by automatically detecting module dependencies and configuring Terrateam accordingly.

## Triggering on Module Updates
When using Terraform modules, you often want to trigger a plan or apply operation in the directories that depend on the module when the module itself is updated. Terrateam allows you to configure this behavior using the [`when_modified`](/reference/configuration/when-modified) directive in your Terrateam configuration file (`.terrateam/config.yml`).

Here's an example configuration that creates a dependency between the `iam` directory and the `modules` directory:
```yaml
dirs:
  modules:
    when_modified:
      file_patterns: []
  iam:
    when_modified:
      file_patterns: ["iam/*.tf", "iam/*.tfvars", "modules/*.tf"]
```

In this configuration:
- The `modules` directory is configured with an empty `file_patterns` list, which means that changes to the `modules` directory itself will not trigger any operations.
- The `iam` directory is configured to trigger a plan operation when changes are made to files matching the patterns `iam/*.tf`, `iam/*.tfvars`, or `modules/*.tf`.

With this setup, when a change is made to a Terraform file in the `modules` directory, Terrateam will automatically trigger a plan operation for the `iam` directory, ensuring that any updates to the module are properly reflected in the dependent directory.

## Automatic Module Discovery
Terrateam's automatic module discovery feature enhances the concept of module dependencies by automatically detecting and configuring them for you. This is made possible by the Terrateam [code indexer](/reference/configuration/indexer), which analyzes your repository structure and Terraform code to determine which directories should be executed during plan and apply operations based on module dependencies.

### How It Works
When the code indexer is enabled, Terrateam creates a map of your repository, including:
- Terraform modules and the directories that reference those modules
- Symbolic links in the repository

Using this information, Terrateam automatically determines:
- Module directories should not be run if they change
- Directories referencing a module should be run if the module changes

This ensures that the appropriate directories are executed based on the module dependencies in your Terraform code, without requiring manual configuration.

### Enabling Automatic Module Discovery
To enable automatic module discovery, you need to configure the [code indexer](/reference/configuration/indexer) in your Terrateam configuration file (`.terrateam/config.yml`).
Here's an example configuration:
```yaml
indexer:
  enabled: true
```

By setting `enabled` to `true`, you enable the code indexer, which automatically discovers module dependencies and generates the necessary Terrateam configuration.

### Example Workflow
Let's walk through an example of how automatic module discovery works in practice:
<Steps>
1. Consider a repository with the following structure:
   ```
   ├── modules
   │   └── vpc
   │       └── main.tf
   └── prod
       └── network
           └── main.tf
   ```
   In this example, the `prod/network` directory references the `vpc` module in the `modules` directory.

2. Enable the code indexer in your `.terrateam/config.yml` file:
   ```yaml
   indexer:
     enabled: true
   ```

3. When a change is made to the `modules/vpc` directory, Terrateam automatically detects that the `prod/network` directory depends on this module.

4. Terrateam generates the necessary configuration to ensure that:

   1\. The `modules/vpc` directory is not run directly

   2\. The `prod/network` directory is run when the `modules/vpc` directory changes

5. When a pull request is opened with changes to the `modules/vpc` directory, Terrateam automatically triggers a plan operation for the `prod/network` directory.

6. Review the plan output and collaborate with your team to ensure the changes are as expected.

7. Apply the changes to `prod/network` by commenting `terrateam apply`.
</Steps>

By leveraging automatic module discovery, Terrateam simplifies your Terraform workflow by automatically detecting and configuring module dependencies, reducing the need for manual configuration.

## Using Modules from a Separate Repository
Terraform allows you to reference modules from external sources, including separate Git repositories. Terrateam supports this workflow, enabling you to use modules from both public and private repositories.

### Public Repositories
To use a module from a public GitHub repository, you can simply reference the repository URL in your Terraform code:
```hcl
module "consul" {
  source = "github.com/opentofu/example"
}
```

Terrateam automatically recognizes `github.com` URLs and will clone the repository as needed during plan and apply operations.

### Private Repositories
To use a module from a private GitHub repository, you need to configure SSH access for Terrateam to clone the repository. Here's how you can set this up:
<Steps>
1. Install the [Terrateam GitHub application](https://github.com/apps/terrateam-action) on your private modules repository. This grants Terrateam the necessary permissions to clone the repository.

2. Generate a new SSH key pair:
   ```
   ssh-keygen -t ed25519 -C "Terrateam SSH Key" -N "" -f ~/.ssh/terrateam-ssh-key
   ```

3. Add the SSH public key to your private modules repository as a deploy key:
   ```
   gh repo deploy-key --repo "OWNER/TERRAFORM-MODULES-REPO" add ~/.ssh/terrateam-ssh-key.pub
   ```

4. Add the SSH private key to your main Terraform repository as a GitHub Actions secret:
   ```
   gh secret --repo "OWNER/TERRAFORM-REPO" set TERRATEAM_SSH_KEY < ~/.ssh/terrateam-ssh-key
   ```

5. Update your Terraform code to reference the private repository using the SSH URL:
   ```hcl
   module "example_module" {
     source = "git::ssh://git@github.com/OWNER/TERRAFORM-MODULES-REPO.git"
   }
   ```
</Steps>

Terrateam will automatically detect the `TERRATEAM_SSH_KEY` secret and configure the necessary SSH access to clone the private repository during plan and apply operations. To add more than one key,
just create additional GitHub Actions secrets using the `TERRATEAM_SSH_KEY_` prefix. For example, `TERRATEAM_SSH_KEY_FOO` and `TERRATEAM_SSH_KEY_BAR`.

### Non-GitHub Repositories
If your modules are stored in a non-GitHub repository, you can still use them with Terrateam by following a similar process:
<Steps>
1. Generate a new SSH key pair:
   ```
   ssh-keygen -t ed25519 -C "Terrateam SSH Key" -N "" -f ~/.ssh/terrateam-ssh-key
   ```

2. Add the SSH public key to your Git hosting provider as an authorized key for your modules repository.

3. Add the SSH private key to your main Terraform repository as a GitHub Actions secret:
   ```
   gh secret --repo "OWNER/TERRAFORM-REPO" set TERRATEAM_SSH_KEY < ~/.ssh/terrateam-ssh-key
   ```

4. Update your Terraform code to reference the repository using the SSH URL:
   ```hcl
   module "example_module" {
     source = "git::ssh://username@example.com/TERRAFORM-MODULES-REPO.git"
   }
   ```

5. Configure Terrateam to perform SSH host key scanning before plan and apply operations by adding the following to your `.terrateam/config.yml`:
   ```yaml
   hooks:
     plan:
       pre:
         - type: run
           cmd: ['ssh-keyscan-pre-hook', 'example.com']
     apply:
       pre:
         - type: run
           cmd: ['ssh-keyscan-pre-hook', 'example.com']
   ```
   The `ssh-keyscan-pre-hook` script is a simple wrapper for the `ssh-keyscan` command that adds the host keys to the known hosts file, ensuring that Terrateam can securely connect to your Git repository.
</Steps>

## Best Practices
When working with Terraform modules and Terrateam, consider the following best practices:
- Keep your modules focused and modular, encapsulating specific functionality or resources.
- Use semantic versioning for your modules, and reference specific versions in your Terraform code to ensure consistency and reproducibility.
- If your modules repository doesn't require Terrateam operations, disable them by adding the following to your `.terrateam/config.yml` in the repository's default branch:
  ```yaml
  enabled: false
  ```
- Use Terrateam's [`when_modified`](/reference/configuration/when-modified) directive to configure dependencies between your modules and the directories that use them, ensuring that changes to modules trigger the necessary plan and apply operations.
- Secure your private modules repositories by using SSH deploy keys and GitHub Actions secrets, and regularly rotate these keys to maintain security.
- Organize your repository structure in a clear and logical manner, separating modules and their respective directories.
